package org.zfx.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Slf4j
public class FileUtils {
	
	/**
	 * 获取Modules的相对地址
	 * @Description 没设置的话默认为"src/main/webapp/qce/modules"
	 * @author zhang_fangxing
	 */
	public static String getPathModulesPath() {
		return "src/main/webapp/qce/modules";
	}
	
	/**
	 * 查看是否含有相关文件
	 * @param path 文件地址
	 * @Description 
	 * @author zhang_fangxing
	 */
	private static boolean existsFile(String path) {
		return new File(path).exists();
	}
	
    /**
     * 生成文件夹o
     * @param path 路径
     * @Description 只生成文件夹不包含任何文件
     * @author zhang_fangxing
     */
    private static void createDir(String path) {
        File folder = new File(path);
        if (!folder.exists() && !folder.isDirectory()) {
            folder.setWritable(true, false);
            folder.mkdirs();
        } else {
        	throw new RuntimeException("文件夹已存在");
        }
    }
	
	/**
	 * 复制整体的modules
	 * @param suffixName 追加后缀名
	 * @Description 最终输入名为modules_${suffixName}
	 * @author zhang_fangxing
	 */
	public static boolean cpModules(String suffixName) {
		String toPath = getPathModulesPath()+"_"+suffixName;
		//如果含有该用户的数据了，则直接报错
		if(existsFile(toPath)) {
			log.error("该用户已含有modules文件，不允许再次复制:"+toPath);
		};
		createDir(toPath);
		return cpFiles(getPathModulesPath(),toPath);
	}

	/**
	 * 复制整体的modules
	 * @param path 路径
	 * @param suffixName 给哪个用户输入的名字
	 * @Description 最终输入名为modules_${suffixName}
	 * @author zhang_fangxing
	 */
	public static boolean cpModules(String path ,String suffixName) {
		String toPath = path+"_"+suffixName;
		createDir(toPath);
		return cpFiles(path,toPath);
	}

	public static boolean cpToRepository(String path ,String toPath){
		createDir(toPath);
		return cpFiles(path,toPath);
	}
	
	/**
	 * 复制整体文件夹
	 * @param fromPath 从...
	 * @param toPath 到...
     * @Description 如果含有该用户的数据了，则直接报错
	 * @author zhang_fangxing
	 */
	private static boolean cpFiles(String fromPath,String toPath) {
		try {
			File source = new File(fromPath);
			File destination = new File(toPath);
	        
	        if (!source.exists()){//如果源文件对象不存在
	        	throw new RuntimeException("源文件对象不存在，请检查磁盘上是否有该文件夹");
	        }
	        if (destination.isFile()){//如果目的文件对象是文件
	        	throw new RuntimeException("给的目的文件对象它是一个文件，不能实现文件夹复制");
	        }
	        if (source.isFile()){//如果源文件对象是文件
	            copyFile(source,destination);
	        }
	        if (source.isDirectory()){//如果源文件对象是文件夹
	            copyDir(source,destination);
	        }
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		 return true;
	}
	
    /**
     * 递归复制文件夹
     * @param file1 源文件
     * @param file2 写入文件
     * @Description 含有递归与非递归的校验。若为非递归的文件，则直接复制文件
     * @author zhang_fangxing
     */
	private static void copyDir(File file1,File file2){
		File[] files = file1.listFiles();
		if (files!=null){
			for (File file:files){
				String fileName = file.getName();
				int lastIndexOf = fileName.lastIndexOf(".");
				if(lastIndexOf != -1) {
					String suffix = fileName.substring(lastIndexOf);
					if(suffix.equals(".git") || suffix.equals(".DS_Store")) {
						continue;
					}
				}
                File tempFile = new File(file2.getAbsoluteFile(),file.getName());
                if (file.isDirectory()){
					tempFile.mkdirs();
					copyDir(file,tempFile);
                }else{
                    copyFile(file,tempFile);
                }
            }
        } else {
        	throw new RuntimeException("未找到任何源文件");
        }
    }
    /**
     * 只复制文件，不涉及递归
     * @param file1 源文件
     * @param file2 写入文件
     * @Description 
     * @author zhang_fangxing
     */
    private static void copyFile(File file1,File file2){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        int length = 0;
        try {
             bis = new BufferedInputStream(new FileInputStream(file1));
             bos = new BufferedOutputStream(new FileOutputStream(file2));
            while((length=bis.read()) != -1){
                bos.write(length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        	closeStream(bis,bos);
        }
    }
    
    /**
     * 常规关闭输入流与输出流的函数
     * @param inputStream 输入流
     * @param outputStream 输出流
     * @Description 含有null值校验
     * @author zhang_fangxing
     */
    private static void closeStream(InputStream inputStream, OutputStream outputStream) {
        if (inputStream != null){
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (outputStream != null){
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}